/**
 * 
 */
package com.android.dwt.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.ListActivity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Resources;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.SearchRecentSuggestions;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ImageButton;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;

import com.android.dwt.R;
import com.android.dwt.TaskItem;
import com.android.dwt.R.color;
import com.android.dwt.R.drawable;
import com.android.dwt.R.id;
import com.android.dwt.R.layout;
import com.android.dwt.data.DBTaskAdapter;
import com.android.dwt.data.GTDApp;
import com.android.dwt.data.MySuggestionsProvider;
import com.android.dwt.util.C;
import com.android.dwt.util.TaskUtil;

/**
 * @author xiang
 *
 */
public class SearchAct extends ListActivity {
	
	private class MyListAdapter extends SimpleExpandableListAdapter {

		private class ViewHolder {
			
			TextView prior;
			CheckBox cb;
			TextView title;
			TextView context;
			TextView position;
//			TextView project;
			TextView tags;

			TextView flag;
		}
		
		private LayoutInflater mInflater;
		
		
		public MyListAdapter(Context context,
				List<? extends Map<String, ?>> groupData, int groupLayout,
				String[] groupFrom, int[] groupTo,
				List<? extends List<? extends Map<String, ?>>> childData,
				int childLayout, String[] childFrom, int[] childTo) {
			
			super(context, groupData, groupLayout, groupFrom, groupTo, childData,
					childLayout, childFrom, childTo);
			// TODO Auto-generated constructor stub
			
			mInflater = LayoutInflater.from(context);
		}
		
		@Override
		public View getChildView(final int groupPosition, final int childPosition,
				boolean isLastChild, View convertView, ViewGroup parent) {
			
//			return super.getChildView(groupPosition, childPosition, isLastChild,
//					convertView, parent);
			
			final ViewHolder holder;
			
			if (convertView == null) {
				
				convertView = mInflater.inflate(R.layout.row_task, null);

				holder = new ViewHolder();
				holder.prior = (TextView) convertView
						.findViewById(R.id.tv_row_prior);

				Log.e(TAG, "convertView is empty: group:"+groupPosition+" children:"+childPosition);

				holder.cb = (CheckBox) convertView.findViewById(R.id.cb_completed);
//				holder.cb.setTag(childPosition);
				holder.title = (TextView) convertView.findViewById(R.id.tv_task);
				holder.context = (TextView) convertView
						.findViewById(R.id.tv_row_context);
				holder.position = (TextView) convertView
						.findViewById(R.id.tv_row_pos);
				// holder.project = (TextView)
				// convertView.findViewById(R.id.tv_row_prj);
				holder.tags = (TextView) convertView.findViewById(R.id.tv_row_tag);
				holder.flag = (TextView) convertView.findViewById(R.id.tv_row_flag);

				convertView.setTag(holder);

			} else {
				
				holder = (ViewHolder) convertView.getTag();
//				holder.cb.setChecked(false);
//				holder.cb.setTag(childPosition);
				
				Log.e(TAG, "convertView not empty: group:"+groupPosition+" children:"+childPosition);
			}

			fillData(holder, groupPosition, childPosition);
			
			return convertView;
		}
		
		private void fillData(final ViewHolder holder, final int groupPosition, final int childPosition) {
			
			// Priority
			String prior = (String) children.get(groupPosition).get(childPosition)
					.get("item_prior");
			if (prior.equals("无")) {
				
				holder.prior.setBackgroundColor(mRsrc.getColor(R.color.none_prior));
				
			} else if (prior.equals("高")) {
				
				holder.prior.setBackgroundColor(mRsrc.getColor(R.color.high_prior));
				
			} else if (prior.equals("中")) {
				
				holder.prior.setBackgroundColor(mRsrc.getColor(R.color.medium_prior));
				
			} else if (prior.equals("低")) {
				
				holder.prior.setBackgroundColor(mRsrc.getColor(R.color.low_prior));
			}

			// CheckBox
			if (holder.cb.isChecked()) {
				
				Log.e(TAG, "children["+groupPosition+"]["+childPosition+"] is checked");
				
			} else {
				
				Log.e(TAG, "children["+groupPosition+"]["+childPosition+"] is unchecked");
			}
			
			int state = (Integer) children.get(groupPosition).get(childPosition).get("item_completed");
			if (state == C.TASK.COMPLETED) {
				
				Log.e(TAG, "task is completed!");
				
				holder.flag.setVisibility(View.VISIBLE);
				holder.cb.setChecked(true);
			}
			
			holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
				
				@Override
				public void onCheckedChanged(CompoundButton buttonView,
						boolean isChecked) {
					
					// TODO Auto-generated method stub
					Log.e("adapter", "checkbox " + childPosition + " checked!");

					HashMap<String, Object> hm = children.get(groupPosition).get(childPosition);
					long rowId = (Long) hm.get("item_id");
					TaskItem ti = mGa.getDbta().getTaskItem(rowId);
					
					String list = ti.getListName();
					int listIndex = TaskUtil.getListIndex(mGa.mList, list);

					if (isChecked) {
						
						holder.flag.setVisibility(View.VISIBLE);

						ti.setCompletedStatus(C.TASK.COMPLETED);
						mGa.getDbta().updateTask(rowId, ti);
						
						SharedPreferences prefs = getSharedPreferences(GTDApp.strList, GTDApp.MODE);
						Editor editor = prefs.edit();
						
						if (listIndex != -1) {		// in some list
							
							// update the counter
							int count = (Integer) mGa.lists.get(listIndex).get("item_count");
							mGa.lists.get(listIndex).put("item_count", count-1);
							
							editor.putInt("List_count["+listIndex+"]", count-1);
							
						} else {
							
//							String list = ti.getListName();
							int index = TaskUtil.getListIndex(mGa.mList, list);
							
							int count = (Integer) mGa.lists.get(index).get("item_count");
							mGa.lists.get(index).put("item_count", count-1);
							
							editor.putInt("List_count["+index+"]", count-1);
						}
						
						editor.commit();
						
					} else {
						
						holder.flag.setVisibility(View.INVISIBLE);

						ti.setCompletedStatus(C.TASK.UNCOMPLETED);
						mGa.getDbta().updateTask(rowId, ti);
						
						SharedPreferences prefs = getSharedPreferences(GTDApp.strList, GTDApp.MODE);
						Editor editor = prefs.edit();
						
						if (listIndex != -1) {
							
							// update the counter
							int count = (Integer) mGa.lists.get(listIndex).get("item_count");
							mGa.lists.get(listIndex).put("item_count", count+1);
							
							
							editor.putInt("List_count["+listIndex+"]", count+1);
							
						} else {
							
							// get original list index
//							String list = ti.getListName();
							int index = TaskUtil.getListIndex(mGa.mList, list);
							
							Log.e(TAG, "original list and its index are: " + list + " " + index);
							
							int count = (Integer) mGa.lists.get(index).get("item_count");
							mGa.lists.get(index).put("item_count", count+1);
							
							editor.putInt("List_count["+index+"]", count+1);
						}
						
						editor.commit();
					}
					
					buttonView.setTag(null);
				}
			});
			
			holder.title.setText((String) children.get(groupPosition)
					.get(childPosition).get("item_name"));

			String ctt = (String) children.get(groupPosition).get(childPosition)
					.get("item_context");
			if (ctt.equals(mGa.getContexts().get(0))) // no context
				holder.context.setText("");
			else
				holder.context.setText("@" + ctt);

			String pos = (String) children.get(groupPosition).get(childPosition)
					.get("item_pos");
			if (pos.equals(mGa.getPositions().get(0).getPlace())) {
				
				holder.position.setText("");
				
			} else {
				
				holder.position.setText("&" + pos);
			}

			
			/*String prj = (String) children.get(groupPosition).get(childPosition).get("item_project");
			if (prj.equals(mGa.getProjects().get(0))) {
				
				holder.project.setText("");
				
			} else {
				
				holder.project.setText("#" + prj);
			}*/
			 

			holder.tags.setText((String) children.get(groupPosition)
					.get(childPosition).get("item_tags"));
		}
		
		@Override
		public View newGroupView(boolean isExpanded, ViewGroup parent) {
			// TODO Auto-generated method stub
//			return super.newGroupView(isExpanded, parent);
			
			return mInflater.inflate(R.layout.grp_search, parent, false);
		}
		
		@Override
		public View getGroupView(int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {
			
			// TODO Auto-generated method stub
//			return super.getGroupView(groupPosition, isExpanded, convertView, parent);
			
			View v = newGroupView(isExpanded, parent);

//			bindGroupView(v, groups.get(groupPosition), mGroupFrom, mGroupTo);
			
			TextView groupName = (TextView) v.findViewById(R.id.tv_search_group);
			groupName.setText((String) groups.get(groupPosition).get("group_name"));
			
			TextView childCount = (TextView) v.findViewById(R.id.tv_search_count);
			int count = (Integer) groups.get(groupPosition).get("child_count");
			if (count == 0) {
				
				childCount.setVisibility(View.INVISIBLE);
				
			} else {
				
				childCount.setVisibility(View.VISIBLE);
				childCount.setText(String.valueOf(count));
			}

			return v;
		}
		
		/*private void bindGroupView(View view, Map<String, Object> data,
				String[] from, int[] to) {
			
			int len = to.length;

			for (int i = 0; i < len; i++) {
				
				TextView v = (TextView) view.findViewById(to[i]);
				if (v != null) {
					
					v.setText((String) data.get(from[i]));
				}
				
			}
			
			return;
		}*/
		
	}		// end class MyListAdapter
	
	
	private final String[] mGroupFrom = new String[] {
			"group_name",
			"child_count" };
	private final int[] mGroupTo = new int[] {
			R.id.tv_search_group,
			R.id.tv_search_count };
	private final String[] fromCols = new String[] {
			"item_name",
			"item_context",
			"item_pos",
			"item_tags"};
	private final int[] toLayouts = new int[] {
			R.id.tv_task,
			R.id.tv_row_context,
			R.id.tv_row_pos,
			R.id.tv_row_tag};
	private final String TAG = "SearchAct";
	
	private GTDApp mGa;
	private ExpandableListView mElv;
	private MyListAdapter mAdapter;
	private ArrayList<HashMap<String, Object>> groups = new ArrayList<HashMap<String, Object>>();
	private ArrayList<ArrayList<HashMap<String, Object>>> children =
			new ArrayList<ArrayList<HashMap<String, Object>>>();
	private int mSearchResult = 0;
	private TextView mTvResult;
	private String queryString;
	
	private Resources mRsrc;
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		
		requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		setContentView(R.layout.panel_search);
		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.tb_search);
		
		initViews();
		
		mGa = (GTDApp) getApplication();
		mRsrc = getResources();
		
		mAdapter = new MyListAdapter(
				this,
				groups,
				R.layout.grp_search,
				mGroupFrom,
				mGroupTo,
				children, R.layout.row_task,
				fromCols,
				toLayouts);
		mElv.setAdapter(mAdapter);
		
//		onSearchRequested();
		
		handleIntent(getIntent());
	}
	
	@Override
	protected void onNewIntent(Intent intent) {
		
		super.onNewIntent(intent);
		
		setIntent(intent);
		handleIntent(intent);
	}
	
	private void handleIntent(Intent intent) {
		
		final String queryAction = intent.getAction();
		if (Intent.ACTION_SEARCH.equals(queryAction)) {
			
			String query = intent.getStringExtra(SearchManager.QUERY).trim();
			saveSearchHistory(query);
			
			updateAdapterData(intent);
			
			mTvResult.setText("\'"+queryString+"\' 的搜索结果共 "+mSearchResult+" 条");
//			Toast.makeText(MainAct.this, query, Toast.LENGTH_LONG).show();
		}
		
	}
	
	private void saveSearchHistory(String query) {
		
		SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
				MySuggestionsProvider.AUTHORITY,
				MySuggestionsProvider.MODE);
		
		suggestions.saveRecentQuery(query, null);
	}
	
	/*private void clearSearchHistory() {
		SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
				MySuggestionsProvider.AUTHORITY,
				MySuggestionsProvider.MODE);
		suggestions.clearHistory();
	}*/

	private void initViews() {
		
		mElv = (ExpandableListView) findViewById(android.R.id.list);
		
//		mElv.setGroupIndicator(null);
		
		mElv.setOnChildClickListener(new OnChildClickListener() {
			
			@Override
			public boolean onChildClick(ExpandableListView parent, View v,
					int groupPosition, int childPosition, long id) {
				
				// TODO Auto-generated method stub
				HashMap<String, Object> hmSelected = (HashMap<String, Object>) children
						.get(groupPosition).get(childPosition);
				
				long posInTable = (Long) hmSelected.get("item_id");
//				int taskStatus = (Integer) hmSelected.get("item_status");
				
				String list = (String) hmSelected.get("item_list");
				int listIndex = TaskUtil.getListIndex(mGa.mList, list);
				
				Intent itt = new Intent(SearchAct.this, TaskDetailAct.class);
				
				itt.putExtra("row_id", posInTable);
//				itt.putExtra("selected_task", hmSelected);
				itt.putExtra("list_index", listIndex);
//				itt.putExtra("task_status", taskStatus);
				
				startActivity(itt);
				
				return false;
			}
		});
		
		mTvResult = (TextView) findViewById(R.id.tv_search);
		
		ImageButton btn_search_back = (ImageButton) findViewById(R.id.btn_search_back);
		btn_search_back.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				SearchAct.this.finish();
			}
		});
		btn_search_back.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				
				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					
					v.setBackgroundResource(R.drawable.back_pressed);
					
				} else if (event.getAction() == MotionEvent.ACTION_UP) {
					
					v.setBackgroundResource(R.drawable.back);
				}

				return false;
			}
			
		});
	}

	
	/*private void getHashArray(Cursor cursor, ArrayList<HashMap<String,Object>> items) {
		HashMap<String, Object> hm;
		
		for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
			long rowId = cursor.getLong(DBTaskAdapter.COL_ID);
			String task = cursor.getString(DBTaskAdapter.COL_TASK_NAME);
			String note = cursor.getString(DBTaskAdapter.COL_TASK_NOTE);
			String list = cursor.getString(DBTaskAdapter.COL_TASK_LIST);
			
			String ctt = cursor.getString(DBTaskAdapter.COL_TASK_CONTEXT);
			String prj = cursor.getString(DBTaskAdapter.COL_TASK_PROJECT);
			String pos = cursor.getString(DBTaskAdapter.COL_TASK_POS);
			
			int status = cursor.getInt(DBTaskAdapter.COL_TASK_STATUS);
			String st = cursor.getString(DBTaskAdapter.COL_TASK_ST);
			String et = cursor.getString(DBTaskAdapter.COL_TASK_ET);
			String repeat = cursor.getString(DBTaskAdapter.COL_TASK_REPEAT);
			String remind = cursor.getString(DBTaskAdapter.COL_TASK_REMIND);
			
			String prior = cursor.getString(DBTaskAdapter.COL_TASK_PRIOR);
			String tags = cursor.getString(DBTaskAdapter.COL_TASK_TAG);
			String created = cursor.getString(DBTaskAdapter.COL_TASK_CREATED);
			int completed = cursor.getInt(DBTaskAdapter.COL_TASK_COMPLETED);
			
			hm = new HashMap<String, Object>();
			hm.put("item_id", rowId);
			hm.put("item_name", task);
			hm.put("item_note", note);
			hm.put("item_list", list);
			
			hm.put("item_context", ctt);
			hm.put("item_project", prj);
			hm.put("item_pos", pos);
			
			hm.put("item_status", status);
			hm.put("item_st", st);
			hm.put("item_et", et);
			hm.put("item_repeat", repeat);
			hm.put("item_remind", remind);
			
			hm.put("item_prior", prior);
			hm.put("item_tags", tags);
			hm.put("item_created", created);
			hm.put("item_completed", completed);
			
			items.add(hm);
		}
	}*/
	
	private void updateAdapterData(Intent intent) {
		
		queryString = intent.getStringExtra(SearchManager.QUERY).trim();
		
		HashMap<String, Object> hm;
		String query;
		
		groups.clear();
		for (int i=0; i<children.size(); i++)
			children.get(i).clear();
		children.clear();
		
		// get number of each task list
		query = "select task_list, count(_id) from " + mGa.getDbta().getTableName()
				+ " where task_name like \'%" + queryString + "%\'"
				+ " or task_note like \'%" + queryString + "%\'"
				+ " group by task_list";
		Cursor listCursor = mGa.getDbta().excuteSQL(query);
		
		Log.e(TAG , "number of groups: "+listCursor.getCount());
		
		if (listCursor.moveToFirst()) {
			
			do {
				
				String listName = listCursor.getString(0);
				int listCount = listCursor.getInt(1);
				
				hm = new HashMap<String, Object>();
				hm.put("group_name", listName);
				hm.put("child_count", listCount);
				
				groups.add(hm);
				
			} while (listCursor.moveToNext());
			
		}
		
		for (int i=0; i<groups.size(); i++) {
			
			children.add(new ArrayList<HashMap<String,Object>>());
		}

		// get selected tasks
		query = "select * from " + mGa.getDbta().getTableName()
				+ " where task_name like \'%" + queryString + "%\'"
				+ " or task_note like \'%" + queryString + "%\'"
				+ " order by task_completed";
		Cursor taskCursor = mGa.getDbta().excuteSQL(query);
		
		for (taskCursor.moveToFirst(); !taskCursor.isAfterLast(); taskCursor.moveToNext()) {
			
			mSearchResult++;
			
			long rowId = taskCursor.getLong(DBTaskAdapter.COL_ID);
			String task = taskCursor.getString(DBTaskAdapter.COL_TASK_NAME);
			String note = taskCursor.getString(DBTaskAdapter.COL_TASK_NOTE);
			String listName = taskCursor.getString(DBTaskAdapter.COL_TASK_LIST);
			String ctt = taskCursor.getString(DBTaskAdapter.COL_TASK_CONTEXT);
			String prj = taskCursor.getString(DBTaskAdapter.COL_TASK_PROJECT);
			String pos = taskCursor.getString(DBTaskAdapter.COL_TASK_POS);
			int status = taskCursor.getInt(DBTaskAdapter.COL_TASK_STATUS);
			String st = taskCursor.getString(DBTaskAdapter.COL_TASK_ST);
			String et = taskCursor.getString(DBTaskAdapter.COL_TASK_ET);
			String repeat = taskCursor.getString(DBTaskAdapter.COL_TASK_REPEAT);
			String remind = taskCursor.getString(DBTaskAdapter.COL_TASK_REMIND);
			String prior = taskCursor.getString(DBTaskAdapter.COL_TASK_PRIOR);
			String tags = taskCursor.getString(DBTaskAdapter.COL_TASK_TAG);
			String created = taskCursor.getString(DBTaskAdapter.COL_TASK_CREATED);
			int completed = taskCursor.getInt(DBTaskAdapter.COL_TASK_COMPLETED);
			
			hm = new HashMap<String, Object>();
			hm.put("item_id", rowId);
			hm.put("item_name", task);
			hm.put("item_note", note);
			hm.put("item_list", listName);
			
			hm.put("item_context", ctt);
			hm.put("item_project", prj);
			hm.put("item_pos", pos);
			
			hm.put("item_status", status);
			hm.put("item_st", st);
			hm.put("item_et", et);
			hm.put("item_repeat", repeat);
			hm.put("item_remind", remind);
			
			hm.put("item_prior", prior);
			hm.put("item_tags", tags);
			hm.put("item_created", created);
			hm.put("item_completed", completed);
			
			int grpIndex = 0;
			for (int j=0; j<groups.size(); j++) {
				
				if (listName.equals(groups.get(j).get("group_name"))) {
					
					grpIndex = j;
					break;
				}
				
			}
			
			children.get(grpIndex).add(hm);
		}
		
		for (int i=0; i<groups.size(); i++) {
			
			mElv.expandGroup(i);
		}
		
		mAdapter.notifyDataSetChanged();
	}
	
	@Override
	public boolean onSearchRequested() {
		
		return super.onSearchRequested();
	}
	
}
